//
// Created by hkkzzxz on 24-9-1.
//

#include "MySQLDatabaseModel.h"

bool MySQLDatabaseModel::queryBool(std::string &query, const std::vector<std::string> &params) {
    MySQLConnectionPool *pool = MySQLConnectionPool::getInstance();
    auto mysqlConn = pool->getConnection();
    if (!mysqlConn) {
        pool->releaseConnection(mysqlConn);
        consoleLogger->error("get MySQL connection failed");
        fileLogger->error("get MySQL connection failed");
        return false;
    }

    consoleLogger->info("get MySQL connection successful");
    try {
        std::unique_ptr<sql::PreparedStatement> prepStmt(mysqlConn->prepareStatement(query));
        for (size_t i = 0; i < params.size(); ++i) {
            prepStmt->setString(i + 1, params[i]);
        }
        std::unique_ptr<sql::ResultSet> res(prepStmt->executeQuery());
        if (res->next()) {
            consoleLogger->info("query successful");
            pool->releaseConnection(mysqlConn);
            return true;
        }
        consoleLogger->info("query failed");
    }
    catch (std::exception const &e) {
        consoleLogger->error("MySQL error: " + std::string(e.what()));
        fileLogger->error("MySQL error: " + std::string(e.what()));
    }
    pool->releaseConnection(mysqlConn);
    return false;
}

bool MySQLDatabaseModel::insert(std::string &insert, const std::vector<std::string> &params) {
    MySQLConnectionPool *pool = MySQLConnectionPool::getInstance();
    auto mysqlConn = pool->getConnection();
    if (!mysqlConn) {
        pool->releaseConnection(mysqlConn);
        consoleLogger->error("Failed to get MySQL connection");
        fileLogger->error("Failed to get MySQL connection");
        return false;
    }

    consoleLogger->info("get MySQL connection successful");
    try {
        std::unique_ptr<sql::PreparedStatement> prepStmt(mysqlConn->prepareStatement(insert));
        for (size_t i = 0; i < params.size(); ++i) {
            prepStmt->setString(i + 1, params[i]);
        }
        if (prepStmt->executeUpdate()) {
            consoleLogger->info("Insert successful");
            pool->releaseConnection(mysqlConn);
            return true;
        }
        consoleLogger->info("Insert failed");
    } catch (const sql::SQLException &e) {
        consoleLogger->error("MySQL error: " + std::string(e.what()));
        fileLogger->error("MySQL error: " + std::string(e.what()));
    }
    pool->releaseConnection(mysqlConn);
    return false;
}

bool MySQLDatabaseModel::update(std::string &update, const std::vector<std::string> &params) {
    MySQLConnectionPool *pool = MySQLConnectionPool::getInstance();
    auto mysqlConn = pool->getConnection();
    if (!mysqlConn) {
        pool->releaseConnection(mysqlConn);
        consoleLogger->error("get MySQL connection failed");
        fileLogger->error("get MySQL connection failed");
        return false;
    }

    consoleLogger->info("get MySQL connection successful");
    try {
        std::unique_ptr<sql::PreparedStatement> prepStmt(mysqlConn->prepareStatement(update));
        for (size_t i = 0; i < params.size(); ++i) {
            prepStmt->setString(i + 1, params[i]);
        }
        if (prepStmt->executeUpdate()) {
            consoleLogger->info("update successful");
            pool->releaseConnection(mysqlConn);
            return true;
        }
        consoleLogger->info("update failed");
    }
    catch (std::exception const &e) {
        consoleLogger->error("MySQL error: " + std::string(e.what()));
        fileLogger->error("MySQL error: " + std::string(e.what()));
    }
    pool->releaseConnection(mysqlConn);
    return false;
}

